#include "StdAfx.h"
#include "Trainer.h"
#include <algorithm>
using namespace std;

static Experiment* gExperiment;

static float fitness(float* weights)
{
	Experiment* experiment = gExperiment;
	copy(weights, weights + experiment->getNeuralWeightsCount(), experiment->getNeuralWeights()); 
	return experiment->getFitness();
}

Trainer::Trainer(Experiment* experiment):
experiment(experiment)
{
	gExperiment = experiment;
	ps.reset(new ParticleSwarm(fitness, experiment->getNeuralWeightsCount(), 20, -20.f, 20.f));
	setNeuralWeights();
}

float Trainer::getFitness() const
{
	return ps->getBestFitness();
}

size_t  Trainer::getIterationCount() const
{
	return ps->getIterationCount();
}

void Trainer::update()
{
	gExperiment = experiment;
	ps->step();
	setNeuralWeights();
}

void Trainer::save(std::ostream& f)
{
	ps->save(f);
}

void Trainer::load(std::istream& f)
{
	ps->load(f);
	setNeuralWeights();
}

void Trainer::setNeuralWeights()
{
	const float* best = ps->getBest();
	copy(best, best + experiment->getNeuralWeightsCount(), experiment->getNeuralWeights()); 
}
